Skip to content

fix - Persist cancelled tool call status when chat is cancelled#240

Merged
jdneo merged 2 commits into
mainfrom
tori/fix-tool-cancel-persist
May 20, 2026
Merged

fix - Persist cancelled tool call status when chat is cancelled#240
jdneo merged 2 commits into
mainfrom
tori/fix-tool-cancel-persist

Conversation

@xinyi-gong
Copy link
Copy Markdown
Member

Summary

Fixes #239.

When a chat response is cancelled while an agent tool call is still running, the live UI shows the tool as cancelled, but the cached conversation can still persist that tool call with running status. Restoring the conversation later reads that persisted status and shows the tool call as running/spinning again.

This change marks cached running tool calls as cancelled before persisting the conversation during the chat cancel flow.

Changes

  • Add persistence handling to convert cached running tool calls to cancelled on chat cancel.
  • Keep the fix scoped to the conversation persistence model, instead of changing confirmation dialog or tool skip behavior.
  • Add coverage to verify only running tool calls are updated while completed tool calls remain unchanged.

@xinyi-gong xinyi-gong marked this pull request as ready for review May 20, 2026 05:54
Copilot AI review requested due to automatic review settings May 20, 2026 05:54
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an inconsistency between the live chat UI and persisted conversation state when a chat is cancelled while an agent tool call is still running, ensuring restored conversations don’t incorrectly show tool calls as still “running”.

Changes:

  • Update the chat cancel flow to persist cached conversations after first converting any persisted running tool-call statuses to cancelled.
  • Add persistence-layer logic to walk cached conversations and update tool-call statuses before saving.
  • Add a unit test to validate that only running tool calls are changed to cancelled.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/ChatView.java Switches cancel flow persistence call to a new “mark running tool calls cancelled + persist” API.
com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/persistence/ConversationPersistenceManager.java Adds a new persistence method that updates cached tool-call statuses before persisting.
com.microsoft.copilot.eclipse.core.test/src/com/microsoft/copilot/eclipse/core/persistence/ConversationPersistenceManagerTests.java Adds coverage verifying running tool calls are converted to cancelled while completed calls are untouched.
Comments suppressed due to low confidence (2)

com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/persistence/ConversationPersistenceManager.java:296

  • markRunningToolCallsCancelledAndPersist returns early (and skips persistence) when no tool call status is updated. This changes behavior from the previous persistCachedConversation call in the cancel flow: cancelling a chat with no currently-running tool calls would no longer persist the cached conversation state to disk. Consider always persisting when the conversation exists (only conditionally mutating tool-call statuses), and update the Javadoc/logic accordingly.
  public CompletableFuture<Void> markRunningToolCallsCancelledAndPersist(String conversationId) {
    if (StringUtils.isBlank(conversationId)) {
      return CompletableFuture.completedFuture(null);
    }

    ConversationData conversationData;
    lock.writeLock().lock();
    try {
      conversationData = conversationCache.get(conversationId);
      if (conversationData == null) {
        return CompletableFuture.completedFuture(null);
      }
      if (!markRunningToolCallsCancelled(conversationData)) {
        return CompletableFuture.completedFuture(null);
      }

com.microsoft.copilot.eclipse.core/src/com/microsoft/copilot/eclipse/core/persistence/ConversationPersistenceManager.java:305

  • This method acquires the write lock and walks the conversation data synchronously before scheduling the async persist. Since ChatView.onCancel() can call this on the UI thread, it can block UI responsiveness if other background persistence/progress tasks are holding the same lock. Consider moving the cache lookup + status update + persist into the CompletableFuture.runAsync block so the UI thread never waits on the lock.
    ConversationData conversationData;
    lock.writeLock().lock();
    try {
      conversationData = conversationCache.get(conversationId);
      if (conversationData == null) {
        return CompletableFuture.completedFuture(null);
      }
      if (!markRunningToolCallsCancelled(conversationData)) {
        return CompletableFuture.completedFuture(null);
      }
    } finally {
      lock.writeLock().unlock();
    }

    return CompletableFuture.runAsync(() -> {
      lock.writeLock().lock();
      try {
        persistAndCacheConversation(conversationData);
      } catch (IOException e) {

@jdneo jdneo merged commit 17d486e into main May 20, 2026
4 checks passed
@jdneo jdneo deleted the tori/fix-tool-cancel-persist branch May 20, 2026 08:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Cancelled terminal tool calling status will become ongoing again after chat history restoration

3 participants